﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.Shell;
using EnvDTE;
using Microsoft.VisualStudio.Shell.Interop;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.VisualStudio;
using System.Xml;

namespace MicroLink.StsDev2008AddIn.CommandHandlers
{
    [CommandID(GuidList.guidStsDev2008AddInCmdSetString, PkgCmdIDList.cmdidAddTargetFile)]
    internal sealed class AddBuildTargetsFile : MenuCommandHandler
    {
        private bool m_enabled;

        public AddBuildTargetsFile(Package package)
            : base(package)
        {
            m_enabled = true;
        }

        protected override void OnExecute(OleMenuCommand command)
        {
            DTE vsDte = ServiceProvider.GetService(typeof(DTE)) as DTE;
            //IVsUIShell uiShell = ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;
            Project project = vsDte.SelectedItems.Item(1).Project;
            //if (uiShell != null && project != null)
            if (project != null)
            {
                ProjectItem item = vsDte.Solution.FindProjectItem("Microsoft.SharePoint.targets");
                if (item != null && item.ContainingProject.FullName == project.FullName)
                {
                    StsDev2008AddInPackage stsPkg = base.Package as StsDev2008AddInPackage;
                    stsPkg.SendMessageToUser("Add StsDev 2008 Targets", "This project already includes a target file.");
                }
                else
                {
                    ProjectItem deploymentFolder = null;
                    try
                    {
                        //Check if the DeploymentFiles folder already exists
                        if (Directory.Exists("DeploymentFiles"))
                        {
                            Directory.Delete("DeploymentFiles");
                        }

                        deploymentFolder = project.ProjectItems.AddFolder("DeploymentFiles", string.Empty);
                        project.ConfigurationManager.AddConfigurationRow("DebugBuild", "", true);
                        AddTargetFile(ref deploymentFolder);
                        project.Save(project.FullName);

                        string projectPath = project.FullName;

                        vsDte.ExecuteCommand("Project.UnloadProject", string.Empty);

                        UpdateProjectFileXml(projectPath);

                        vsDte.ExecuteCommand("Project.ReloadProject", string.Empty);
                    }
                    catch (COMException comEx)
                    {
                        if (deploymentFolder != null)
                            deploymentFolder.Delete();

                        StsDev2008AddInPackage stsDev = base.Package as StsDev2008AddInPackage;
                        stsDev.SendMessageToUser("Project Item Error", comEx.Message, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_CRITICAL);
                    }
                    finally
                    {
                        if (File.Exists(base.Package.UserLocalDataPath + @"\Microsoft.SharePoint.targets"))
                            File.Delete(base.Package.UserLocalDataPath + @"\Microsoft.SharePoint.targets");
                    }
                }
            }
        }

        protected override void OnQueryStatus(OleMenuCommand command)
        {
            DTE vsDte = ServiceProvider.GetService(typeof(DTE)) as DTE;
            if (vsDte != null)
            {
                command.Enabled = !ProjectIncludesTargetFile(ref vsDte);
                return;
            }

            command.Enabled = false;
        }

        private void AddTargetFile(ref ProjectItem targetFileContainer)
        {
            FileStream tempTargetFile = File.Create(base.Package.UserLocalDataPath + @"\Microsoft.SharePoint.targets");
            tempTargetFile.Write(Resources.StsDev2008, 0, Resources.StsDev2008.Length);
            tempTargetFile.Close();

            targetFileContainer.ProjectItems.AddFromTemplate(
                base.Package.UserLocalDataPath + @"\Microsoft.SharePoint.targets",
                "Microsoft.SharePoint.targets");
        }

        private void UpdateProjectFileXml(string projectFilePath)
        {
            XmlDocument projectFile = new XmlDocument();
            projectFile.Load(projectFilePath);

            //projectFile.DocumentElement.InnerXml += 
            //"<PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'DebugBuild|AnyCPU' \">"
            //  + "<OutputPath>bin\\Debug\\</OutputPath>"
            //  + "<DebugSymbols>true</DebugSymbols>"
            //  + "<DebugType>full</DebugType>"
            //  + "<Optimize>false</Optimize>"
            //  + "<DefineConstants>DEBUG;TRACE</DefineConstants>"
            //  + "<ErrorReport>prompt</ErrorReport>"
            //  + "<WarningLevel>4</WarningLevel>"
            //  + "<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>"
            //+ "</PropertyGroup>";

            XmlNamespaceManager ns = new XmlNamespaceManager(projectFile.NameTable);
            ns.AddNamespace("stsdev", projectFile.DocumentElement.NamespaceURI);

            XmlNodeList xmlNodes = projectFile.DocumentElement.SelectNodes(@"//stsdev:PropertyGroup", ns);
            foreach (XmlNode propertyGroup in xmlNodes)
            {
                try
                {
                    XmlAttribute condition = propertyGroup.Attributes.GetNamedItem("Condition") as XmlAttribute;
                    if (condition != null)
                    {
                        if (condition.Value.Contains("'$(Configuration)|$(Platform)' == 'DebugBuild|AnyCPU'"))
                        {
                            propertyGroup.InnerXml = "<OutputPath>bin\\Debug\\</OutputPath>"
                                + "<DebugSymbols>true</DebugSymbols>"
                                + "<DebugType>full</DebugType>"
                                + "<Optimize>false</Optimize>"
                                + "<DefineConstants>DEBUG;TRACE</DefineConstants>"
                                + "<ErrorReport>prompt</ErrorReport>"
                                + "<WarningLevel>4</WarningLevel>"
                                + "<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>";
                        }
                    }
                    else if (propertyGroup.Attributes.Count == 0) // This is the project property group
                    {
                        propertyGroup.InnerXml += "<GenerateResourceNeverLockTypeAssemblies>true</GenerateResourceNeverLockTypeAssemblies>";
                    }
                }
                catch
                {
                }
            }

            /*
            XmlElement propertyGroup = projectFile.CreateElement("PropertyGroup", projectFile.DocumentElement.NamespaceURI);
            propertyGroup.SetAttribute("Condition", projectFile.DocumentElement.NamespaceURI, "'$(Configuration)|$(Platform)' == 'DebugBuild|AnyCPU'");

            XmlElement outputPath = projectFile.CreateElement("OutputPath", projectFile.DocumentElement.NamespaceURI);
            outputPath.InnerText = @"bin\Debug\";
            propertyGroup.AppendChild(outputPath);

            XmlElement debugSymbols = projectFile.CreateElement("DebugSymbols", projectFile.DocumentElement.NamespaceURI);
            debugSymbols.InnerText = true.ToString();
            propertyGroup.AppendChild(debugSymbols);

            XmlElement debugType = projectFile.CreateElement("DebugType", projectFile.DocumentElement.NamespaceURI);
            debugType.InnerText = "full";
            propertyGroup.AppendChild(debugType);

            XmlElement optimize = projectFile.CreateElement("Optimize", projectFile.DocumentElement.NamespaceURI);
            optimize.InnerText = false.ToString();
            propertyGroup.AppendChild(optimize);

            XmlElement defineConstants = projectFile.CreateElement("DefineConstants", projectFile.DocumentElement.NamespaceURI);
            defineConstants.InnerText = "DEBUG;TRACE";
            propertyGroup.AppendChild(defineConstants);

            XmlElement errorReport = projectFile.CreateElement("ErrorReport", projectFile.DocumentElement.NamespaceURI);
            errorReport.InnerText = "prompt";
            propertyGroup.AppendChild(errorReport);

            XmlElement warningLevel = projectFile.CreateElement("WarningLevel", projectFile.DocumentElement.NamespaceURI);
            warningLevel.InnerText = "4";
            propertyGroup.AppendChild(warningLevel);

            XmlElement generateSerializationAssembly = projectFile.CreateElement("GenerateSerializationAssemblies", projectFile.DocumentElement.NamespaceURI);
            generateSerializationAssembly.InnerText = "Off";
            propertyGroup.AppendChild(generateSerializationAssembly);

            projectFile.DocumentElement.AppendChild(propertyGroup);
            */

            projectFile.DocumentElement.InnerXml +=
                "<Import Project=\"DeploymentFiles\\Microsoft.SharePoint.targets\" />";
            /*
            XmlElement importElement = projectFile.CreateElement("Import", projectFile.DocumentElement.NamespaceURI);
            importElement.SetAttribute("Project", projectFile.DocumentElement.NamespaceURI, @"DeploymentFiles\Microsoft.SharePoint.targets");
            projectFile.DocumentElement.AppendChild(importElement);
            */

            projectFile.DocumentElement.InnerXml +=
                "<Target Name=\"AfterBuild\">"
                + "<CallTarget Targets=\"DebugBuild\" Condition=\" '$(Configuration)|$(Platform)' == 'DebugBuild|AnyCPU' \" />"
                + "</Target>";
            /*
            XmlElement target = projectFile.CreateElement("Target", projectFile.DocumentElement.NamespaceURI);
            target.SetAttribute("Name", projectFile.DocumentElement.NamespaceURI, "AfterBuild");

            XmlElement callTarget = projectFile.CreateElement("CallTarget", projectFile.DocumentElement.NamespaceURI);
            callTarget.SetAttribute("Targets", projectFile.DocumentElement.NamespaceURI, "DebugBuild");
            callTarget.SetAttribute("Condition", projectFile.DocumentElement.NamespaceURI, "'$(Configuration)|$(Platform)' == 'DebugBuild|AnyCPU'");

            target.AppendChild(callTarget);
            projectFile.DocumentElement.AppendChild(target);
            */
            projectFile.Save(projectFilePath);
        }

        private bool ProjectIncludesTargetFile(ref DTE theDte)
        {
            Project project = theDte.SelectedItems.Item(1).Project;
            ProjectItem targetFileItem = theDte.Solution.FindProjectItem("Microsoft.SharePoint.targets");
            if (project != null)
            {
                ProjectItem item = theDte.Solution.FindProjectItem("Microsoft.SharePoint.targets");
                if (item != null && item.ContainingProject.FullName == project.FullName)
                {
                    return true;
                }
            }

            return false;
        }
    }
}
